home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / castools.zip / REMOVEFR.C < prev    next >
Text File  |  1990-02-13  |  6KB  |  242 lines

  1.  
  2.  
  3. /*
  4.    REMOVEFR.C Function PbRemoverFromGroup:  Removers a person entry from
  5.       a group entry.
  6.  
  7.    INPUT:  Phonebook structure, and the record id's of the person and group
  8.       entries.
  9.  
  10.    OUTPUT: If successful, removes the person from the group's members list, and
  11.       removes the group from the person's members list.  If the change in
  12.       membership affects the group's HardwareType, that field is changed.
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <malloc.h>
  17. #include <phonebk.h>
  18.  
  19. int pascal PbRemoveFromGroup(PB *pb, int GroupID, int MemberID)
  20. {
  21.  
  22.   int i, j, k;
  23.   PBE *group = NULL,
  24.       *person = NULL;
  25.   int retval = FAIL;
  26.   int writ;                                  /* for return from fwrite() */
  27.   LONGWORD offset,
  28.            group_offset,
  29.            person_offset;
  30.   int temperrno = 0;                         /* for saving Pberrno aside */
  31.   BYTE hasccc = HASCCC;                      /* for changing a group h/w type */
  32.  
  33.   Pberrno = 0;                               /* Initially, always reset */
  34.  
  35.   /* First, check params */
  36.   if (pb == NULL) {
  37.     Pberrno = INVALIDPARAMETER;
  38.     return(NULL);
  39.   }
  40.   if ((GroupID < 0) ||
  41.       (GroupID > 999)) {
  42.     Pberrno = INVALIDPARAMETER;
  43.     return(NULL);
  44.   }
  45.   if ((MemberID < 0) ||
  46.       (MemberID > 999)) {
  47.     Pberrno = INVALIDPARAMETER;
  48.     return(NULL);
  49.   }
  50.  
  51.   /* Check that this slight increase of 'free bytes' does not go the limit */
  52.   if ((pb->header.FreeBytes + 2*sizeof(int)) > MAXUNUSEDBYTES) {
  53.     Pberrno = TOOMANYFREEBYTES;
  54.   }
  55.  
  56.   /* Fetch the entries involved */
  57.   if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
  58.     goto getout;
  59.   }
  60.   group_offset = OffsetOfEntry(pb, GroupID);
  61.   if (!(person = PbGetEntry(pb, NULL, NULL, MemberID))) {
  62.     goto getout;
  63.   }
  64.   person_offset = OffsetOfEntry(pb, MemberID);
  65.  
  66.   /* Check that the group IS a group and the person IS a person */
  67.   if (group->type != GROUPENTRY) {
  68.     Pberrno = GROUPCANTBEMEMBER;
  69.     goto getout;
  70.   }
  71.   if (person->type != PERSONENTRY) {
  72.     Pberrno = PERSONCANTHAVEMEMBER;
  73.     goto getout;
  74.   }
  75.  
  76.   /* Check that each IS in the others members list, and set indexes to them */
  77.   for (i=0; i<group->members; i++) {
  78.     if (group->MemberList[i] == MemberID) {
  79.       break;
  80.     }
  81.   }
  82.   if (i == group->members) {
  83.     Pberrno = GROUPDOESNTHAVEMEMBER;
  84.     goto getout;
  85.   }
  86.  
  87.   for (j=0; j<person->members; j++) {
  88.     if (person->MemberList[j] == GroupID) {
  89.       break;
  90.     }
  91.   }
  92.   if (j == person->members) {
  93.     Pberrno = MEMBERDOESNTHAVEGROUP;
  94.     goto getout;
  95.   }
  96.  
  97.   /* Check if this will affect the hardware type of the group */
  98.   if ((group->HardwareType == FAXONLY) && (person->HardwareType == FAXONLY)) {
  99.  
  100.     /* check all members except the current one */
  101.     for (k=0; k<group->members; k++) {
  102.       if (group->MemberList[k] != MemberID) {
  103.         if (HardwareTypeOf(pb, group->MemberList[k], &offset) == FAXONLY) {
  104.           break;
  105.         }
  106.       }
  107.     }
  108.  
  109.     /* If all other members of the group were HASCCC, time to change group */
  110.     if (k == group->members) {
  111.       if (fseek(pb->fp, group_offset + 7L, SEEK_SET)) {
  112.         Pberrno = FSEEKERROR;
  113.         goto getout;
  114.       }
  115.       writ = fwrite(&hasccc, sizeof(BYTE), 1, pb->fp);
  116.       if (writ != 1) {
  117.         Pberrno = CANTWRITE;
  118.         goto getout;
  119.       }
  120.     }
  121.   }
  122.  
  123.   /* ...remove the membership ID's by writes to the fields on the file */
  124.   /* Do this by writing the last member in the list over the one being removed*/
  125.   offset =  group_offset + group->length -
  126.             ((group->members - i) * sizeof(int));
  127.   if (fseek(pb->fp, offset, SEEK_SET)) {
  128.     Pberrno = FSEEKERROR;
  129.     goto getout;
  130.   }
  131.   writ = fwrite(&group->MemberList[group->members - 1],
  132.                 sizeof(int),
  133.                 1,
  134.                 pb->fp);
  135.   if (writ != 1) {
  136.     Pberrno = CANTWRITE;
  137.     goto getout;
  138.   }
  139.  
  140.   /* Now, update the length */
  141.   if (fseek(pb->fp, group_offset + 4L, SEEK_SET)) {
  142.     Pberrno = FSEEKERROR;
  143.     goto getout;
  144.   }
  145.   group->length -= sizeof(int);
  146.   writ = fwrite(&group->length, sizeof(int), 1, pb->fp);
  147.   if (writ != 1) {
  148.     Pberrno = CANTWRITE;
  149.     goto getout;
  150.   }
  151.  
  152.   /* and finally update the members count */
  153.   group->members--;
  154.   if (fseek(pb->fp, group_offset + 2L, SEEK_SET)) {
  155.     Pberrno = FSEEKERROR;
  156.     goto getout;
  157.   }
  158.   writ = fwrite(&group->members, sizeof(int), 1, pb->fp);
  159.   if (writ != 1) {
  160.     Pberrno = CANTWRITE;
  161.     goto getout;
  162.   }
  163.  
  164.   /* Now, for the person entry's fields */
  165.   offset = person_offset + person->length -
  166.            ((person->members - j) * sizeof(int));
  167.  
  168.   if (fseek(pb->fp, offset, SEEK_SET)) {
  169.     Pberrno = FSEEKERROR;
  170.     goto getout;
  171.   }
  172.   writ = fwrite(&person->MemberList[person->members - 1],
  173.                 sizeof(int),
  174.                 1,
  175.                 pb->fp);
  176.   if (writ != 1) {
  177.     Pberrno = CANTWRITE;
  178.     goto getout;
  179.   }
  180.   /* Now, update the length */
  181.   if (fseek(pb->fp, person_offset + 4L, SEEK_SET)) {
  182.     Pberrno = FSEEKERROR;
  183.     goto getout;
  184.   }
  185.   person->length -= sizeof(int);
  186.   writ = fwrite(&person->length, sizeof(int), 1, pb->fp);
  187.   if (writ != 1) {
  188.     Pberrno = CANTWRITE;
  189.     goto getout;
  190.   }
  191.  
  192.   /* and finally update the members count */
  193.   person->members--;
  194.   if (fseek(pb->fp, person_offset + 2L, SEEK_SET)) {
  195.     Pberrno = FSEEKERROR;
  196.     goto getout;
  197.   }
  198.   writ = fwrite(&person->members, sizeof(int), 1, pb->fp);
  199.   if (writ != 1) {
  200.     Pberrno = CANTWRITE;
  201.     goto getout;
  202.   }
  203.  
  204.   /* Tweak the phonebook's 'free bytes' field */
  205.   if (fseek(pb->fp, 6L, SEEK_SET)) {
  206.     Pberrno = FSEEKERROR;
  207.     goto getout;
  208.   }
  209.   pb->header.FreeBytes += 2 * sizeof(int);
  210.   writ = fwrite(&pb->header.FreeBytes, sizeof(BYTE), 1, pb->fp);
  211.   if (writ != 1) {
  212.     Pberrno = CANTWRITE;
  213.     goto getout;
  214.   }
  215.  
  216.   if (!group->members) {                     /* last member: remove group */
  217.     if (!(PbRemoveEntry(pb, GroupID))) {
  218.       goto getout;
  219.     }
  220.   }
  221.  
  222.   /* If we got here, all went well! */
  223.   retval = SUCCESS;
  224.  
  225. getout:
  226.  
  227.   /* first save Pberrno aside because PbFreePBE would reset it */
  228.   if (Pberrno) {
  229.     temperrno = Pberrno;
  230.   }
  231.   if (group) {
  232.     PbFreePBE(pb, group);
  233.   }
  234.   if (person) {
  235.     PbFreePBE(pb, person);
  236.   }
  237.   if (temperrno) {
  238.     Pberrno = temperrno;
  239.   }
  240.   return(retval);
  241. }
  242.